//package com.liuyu.common.framework.rocketmq.kits;
//
//import com.alibaba.fastjson.JSON;
//import com.liuyu.common.framework.rocketmq.strategy.service.facade.TransactionServiceStrategy;
//import com.liuyu.common.framework.rocketmq.vo.MqMessage;
//import com.liuyu.common.framework.rocketmq.vo.QueueMessage;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.rocketmq.client.producer.LocalTransactionState;
//import org.apache.rocketmq.client.producer.TransactionListener;
//import org.apache.rocketmq.client.producer.TransactionMQProducer;
//import org.apache.rocketmq.client.producer.TransactionSendResult;
//import org.apache.rocketmq.common.message.Message;
//import org.apache.rocketmq.common.message.MessageExt;
//import org.apache.rocketmq.spring.core.RocketMQTemplate;
//import org.apache.rocketmq.spring.support.RocketMQHeaders;
//import org.springframework.beans.BeansException;
//import org.springframework.beans.factory.BeanInitializationException;
//import org.springframework.beans.factory.InitializingBean;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.ApplicationContextAware;
//import org.springframework.context.ApplicationContextException;
//import org.springframework.context.ApplicationEventPublisherAware;
//import org.springframework.context.MessageSourceAware;
//import org.springframework.context.ResourceLoaderAware;
//import org.springframework.messaging.support.MessageBuilder;
//import org.springframework.stereotype.Component;
//
///**
// * 事务消息抽象类
// * @author: liuyu
// * @date: 2022/4/9 20:38
// * @version: 1
// */
//@Slf4j
//public class AbstractRocketTransactionListener implements TransactionListener, ApplicationContextAware {
//
//    protected static ApplicationContext APPLICATION_CONTEXT;
//    @Autowired
//    private RocketMQTemplate rocketMQTemplate;
//
//    public static final int MAX_TRY_TIMES = 3;
//
//    /**
//     * 事务重试次数。最多18次，是根据时间类确定的。
//     * @author liuyu
//     * @date 2022/4/9 22:08
//     * @return int
//     */
//    protected int getMaxTryTimes() {
//        return MAX_TRY_TIMES;
//    }
//
//    @Override
//    public LocalTransactionState executeLocalTransaction(Message message, Object o) {
//        String transId = message.getTransactionId();
//        boolean result = ((TransactionServiceStrategy) APPLICATION_CONTEXT.getBean(this.getClass())).executeTransaction(message, o);
//        //如果这里执行成功，则直接进行提交
//        if (result) {
//            if (log.isDebugEnabled()) {
//                log.debug("事务消息：{}提交", transId);
//            }
//            return LocalTransactionState.COMMIT_MESSAGE;
//        }
//        return LocalTransactionState.UNKNOW;
//    }
//
//
//    @Override
//    public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
//        String transId = messageExt.getTransactionId();
////        进行本地事务校验
//        boolean result = ((TransactionServiceStrategy) APPLICATION_CONTEXT.getBean(this.getClass())).checkTransaction(messageExt);
//        //成功，则提交
//        if (result) {
//            if (log.isDebugEnabled()) {
//                log.debug("事务消息：{} 本地校验成功提交", transId);
//            }
//            return LocalTransactionState.COMMIT_MESSAGE;
//        }
        //未成功，且未达到最大重试次数，继续
//        int tryTimes = messageExt.getReconsumeTimes();
//        if (tryTimes < getMaxTryTimes()) {
//            if (log.isDebugEnabled()) {
//                log.debug("事务消息：{} 本地校验失败", transId);
//            }
//            return LocalTransactionState.UNKNOW;
//        } else {
//            //未成功，且已经达到了最大重试次数，回滚
//            if (log.isDebugEnabled()) {
//                log.debug("事务消息：{} 本地校验失败回滚", transId);
//            }
//            //如果失败，则需要做的事情
//            ((TransactionServiceStrategy) APPLICATION_CONTEXT.getBean(this.getClass())).transactionFail(messageExt);
//            return LocalTransactionState.ROLLBACK_MESSAGE;
//        }
//    }
//
//    /**
//     * Set the ApplicationContext that this object runs in.
//     * Normally this call will be used to initialize the object.
//     * <p>Invoked after population of normal bean properties but before an init callback such
//     * as {@link InitializingBean#afterPropertiesSet()}
//     * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
//     * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
//     * {@link MessageSourceAware}, if applicable.
//     * @param applicationContext the ApplicationContext object to be used by this object
//     * @throws ApplicationContextException in case of context initialization errors
//     * @throws BeansException if thrown by application context methods
//     * @see BeanInitializationException
//     */
//    @Override
//    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        APPLICATION_CONTEXT = applicationContext;
//    }
//
//
//    /**
//     * 发送事务消息
//     * @author liuyu
//     * @date 2021/12/23 11:05
//     * @param topicName
//     * @param message
//     * @param extend
//     * @return org.apache.rocketmq.client.producer.TransactionSendResult
//     */
//    public <T> TransactionSendResult sendMessageInTransaction(String topicName, QueueMessage<T> message, Object extend) {
//        String messages = JSON.toJSONString(message);
//        org.springframework.messaging.Message message1 = MessageBuilder.withPayload(messages).setHeader(RocketMQHeaders.KEYS, "").build();
//        // 此处如果使用MQ其他版本，可能导致强转异常,设置监听器
//        ((TransactionMQProducer) rocketMQTemplate.getProducer()).setTransactionListener(this);
//        TransactionSendResult transactionSendResult = rocketMQTemplate.sendMessageInTransaction(topicName, message1, extend);
//        log.info("事务消息-本地事务执行状态：{},{}" + transactionSendResult.toString(), transactionSendResult.getLocalTransactionState().name());
//        return transactionSendResult;
//    }
//
//    /**
//     * 发送普通的消息
//     *
//     * @author liuyu
//     * @date 2021/7/29 15:04
//     * @param topic
//     * @param message
//     * @return void
//     */
//    <T> void sendTransactionMessage(String topic, MqMessage<T> message) {
//        // 此处如果使用MQ其他版本，可能导致强转异常,设置监听器
//        ((TransactionMQProducer) rocketMQTemplate.getProducer()).setTransactionListener(this);
//
//    }
//
//}
